package com.srtp.secureprotocol.cipherstream;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 摘要计算输出流
 * 继承自FilterOutputStream，在数据写入底层输出流的同时计算SHA-256摘要
 *
 * 主要功能：
 * 1. 透明计算写入数据的哈希值
 * 2. 在flush操作时完成最终摘要计算
 * 3. 提供获取数据摘要的方法
 *
 * 使用场景：文件加密/解密过程中验证数据完整性
 */
public abstract class DigestingOutputStream extends FilterOutputStream {

    private final MessageDigest runningDigest;  // 运行中的摘要计算器
    private byte[] digest;                     // 最终计算得到的摘要值

    /**
     * 构造函数
     * @param outputStream 底层输出流
     */
    public DigestingOutputStream(OutputStream outputStream) {
        super(outputStream);
        try {
            // 初始化SHA-256摘要计算器
            this.runningDigest = MessageDigest.getInstance("SHA256");
        } catch (NoSuchAlgorithmException e) {
            // SHA-256是Java标准算法，理论上不会发生此异常
            throw new AssertionError(e);
        }
    }

    @Override
    public void write(byte[] buffer) throws IOException {
        // 更新摘要并写入数据
        runningDigest.update(buffer, 0, buffer.length);
        out.write(buffer, 0, buffer.length);
    }

    @Override
    public void write(byte[] buffer, int offset, int length) throws IOException {
        // 更新摘要并写入指定范围数据
        runningDigest.update(buffer, offset, length);
        out.write(buffer, offset, length);
    }

    @Override
    public void write(int b) throws IOException {
        // 更新单个字节的摘要并写入
        runningDigest.update((byte)b);
        out.write(b);
    }

    @Override
    public void flush() throws IOException {
        // 完成摘要计算（注意：digest()调用后摘要器会被重置）
        digest = runningDigest.digest();
        out.flush();
    }

    @Override
    public void close() throws IOException {
        out.close();
    }

    /**
     * 获取已传输数据的摘要
     * 注意：必须在flush()后调用才能获取有效摘要
     *
     * @return SHA-256摘要字节数组
     */
    public byte[] getTransmittedDigest() {
        return digest;
    }
}